/* Includes ------------------------------------------------------------------*/
#include "board.h"
/* Private define ---------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/
/**
 * @brief LED variables
 */
GPIO_TypeDef* LED_PORT[LEDn] = {LED1_GPIO_PORT, 
                                LED2_GPIO_PORT, 
                                LED3_GPIO_PORT,
                                LED4_GPIO_PORT};

const uint16_t LED_PIN[LEDn] = {LED1_PIN, 
                                LED2_PIN, 
                                LED3_PIN,
                                LED4_PIN};

GPIO_TypeDef* PWR_PORT[LEDn] = {PWR1_GPIO_PORT, 
                                PWR2_GPIO_PORT, 
                                PWR3_GPIO_PORT,
                                PWR4_GPIO_PORT};

const uint16_t PWR_PIN[LEDn] = {PWR1_PIN, 
                                PWR2_PIN, 
                                PWR3_PIN,
                                PWR4_PIN};
/**
 * @brief BUTTON variables
 */
GPIO_TypeDef* BUTTON_PORT[BUTTONn] = {WAKEUP_BUTTON_GPIO_PORT, 
                                      TAMPER_BUTTON_GPIO_PORT,
                                      KEY_BUTTON_GPIO_PORT,
                                      DOOR_BUTTON_GPIO_PORT}; 

const uint16_t BUTTON_PIN[BUTTONn] = {WAKEUP_BUTTON_PIN, 
                                      TAMPER_BUTTON_PIN,
                                      KEY_BUTTON_PIN,
                                      DOOR_BUTTON_PIN}; 
                                             
const uint16_t BUTTON_IRQn[BUTTONn] = {WAKEUP_BUTTON_EXTI_IRQn, 
                                       TAMPER_BUTTON_EXTI_IRQn,
                                       KEY_BUTTON_EXTI_IRQn,
                                       DOOR_BUTTON_EXTI_IRQn};

/**
 * @brief LED variables
 */
GPIO_TypeDef* RS485_PORT[LEDn] = {RS4851_GPIO_PORT, 
                                RS4852_GPIO_PORT, 
                                RS4853_GPIO_PORT,
                                RS4854_GPIO_PORT};

const uint16_t RS485_PIN[LEDn] = {RS4851_PIN, 
                                RS4852_PIN, 
                                RS4853_PIN,
                                RS4854_PIN};
/* Private function prototypes -----------------------------------------------*/

/* Private functions ---------------------------------------------------------*/
/**
  * @brief  Configures LED GPIO.
  * @param  Led: Specifies the Led to be configured. 
  *   This parameter can be one of following parameters:
  *     @arg LED1
  *     @arg LED2
  *     @arg LED3
  *     @arg LED4
  */
void BSP_LED_Init(Led_TypeDef Led)
{
  GPIO_InitTypeDef  gpioinitstruct = {0};
  
  /* Enable the GPIO_LED clock */
  LEDx_GPIO_CLK_ENABLE(Led);

  /* Configure the GPIO_LED pin */
  gpioinitstruct.Pin    = LED_PIN[Led];
  gpioinitstruct.Mode   = GPIO_MODE_OUTPUT_PP;
  gpioinitstruct.Pull   = GPIO_NOPULL;
  gpioinitstruct.Speed  = GPIO_SPEED_FREQ_HIGH;

  HAL_GPIO_Init(LED_PORT[Led], &gpioinitstruct);

  HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_RESET);
}

/**
  * @brief  Turns selected LED On.
  * @param  Led: Specifies the Led to be set on. 
  *   This parameter can be one of following parameters:
  *     @arg LED1
  *     @arg LED2
  *     @arg LED3
  *     @arg LED4
  */
void BSP_LED_On(Led_TypeDef Led)
{
  HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_SET);
}

/**
  * @brief  Turns selected LED Off.
  * @param  Led: Specifies the Led to be set off. 
  *   This parameter can be one of following parameters:
  *     @arg LED1
  *     @arg LED2
  *     @arg LED3
  *     @arg LED4
  */
void BSP_LED_Off(Led_TypeDef Led)
{
  HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_RESET);
}

/**
  * @brief  Toggles the selected LED.
  * @param  Led: Specifies the Led to be toggled. 
  *   This parameter can be one of following parameters:
  *     @arg LED1
  *     @arg LED2
  *     @arg LED3
  *     @arg LED4
  * @retval None
  */
void BSP_LED_Toggle(Led_TypeDef Led)
{
  HAL_GPIO_TogglePin(LED_PORT[Led], LED_PIN[Led]);
}

/**
  * @brief  Configures LED GPIO.
  * @param  Led: Specifies the Led to be configured. 
  *   This parameter can be one of following parameters:
  *     @arg PWR1
  *     @arg PWR2
  *     @arg PWR3
  *     @arg PWR4
  */
void BSP_PWR_Init(Pwr_TypeDef Pwr)
{
  GPIO_InitTypeDef  gpioinitstruct = {0};
  
  /* Enable the GPIO_LED clock */
  PWRx_GPIO_CLK_ENABLE(Pwr);

  /* Configure the GPIO_LED pin */
  gpioinitstruct.Pin    = PWR_PIN[Pwr];
  gpioinitstruct.Mode   = GPIO_MODE_OUTPUT_PP;
  gpioinitstruct.Pull   = GPIO_NOPULL;
  gpioinitstruct.Speed  = GPIO_SPEED_FREQ_HIGH;

  HAL_GPIO_Init(PWR_PORT[Pwr], &gpioinitstruct);

  HAL_GPIO_WritePin(PWR_PORT[Pwr], PWR_PIN[Pwr], GPIO_PIN_RESET);
}

/**
  * @brief  Turns selected LED On.
  * @param  Led: Specifies the Led to be set on. 
  *   This parameter can be one of following parameters:
  *     @arg PWR1
  *     @arg PWR2
  *     @arg PWR3
  *     @arg PWR4
  */
void BSP_PWR_On(Pwr_TypeDef Pwr)
{
  HAL_GPIO_WritePin(PWR_PORT[Pwr], PWR_PIN[Pwr], GPIO_PIN_SET);
}

/**
  * @brief  Turns selected LED Off.
  * @param  Led: Specifies the Led to be set off. 
  *   This parameter can be one of following parameters:
  *     @arg PWR1
  *     @arg PWR2
  *     @arg PWR3
  *     @arg PWR4
  */
void BSP_PWR_Off(Pwr_TypeDef Pwr)
{
  HAL_GPIO_WritePin(PWR_PORT[Pwr], PWR_PIN[Pwr], GPIO_PIN_RESET);
}

/**
  * @brief  Configures push button GPIO and EXTI Line.
  * @param  Button: Button to be configured.
  *   This parameter can be one of the following values: 
  *     @arg BUTTON_WAKEUP: Wakeup Push Button 
  *     @arg BUTTON_TAMPER: Tamper Push Button 
  *     @arg BUTTON_KEY: Key Push Button 
  * @param  Button_Mode: Button mode requested.
  *   This parameter can be one of the following values:   
  *     @arg BUTTON_MODE_GPIO: Button will be used as simple IO 
  *     @arg BUTTON_MODE_EXTI: Button will be connected to EXTI line
  *                            with interrupt generation capability
  */
void BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef Button_Mode)
{
  GPIO_InitTypeDef gpioinitstruct = {0};

  /* Enable the corresponding Push Button clock */
  BUTTONx_GPIO_CLK_ENABLE(Button);
  
  /* Configure Push Button pin as input */
  gpioinitstruct.Pin    = BUTTON_PIN[Button];
  gpioinitstruct.Pull   = GPIO_NOPULL;
  gpioinitstruct.Speed  = GPIO_SPEED_FREQ_HIGH;
    
  if (Button_Mode == BUTTON_MODE_GPIO)
  {
    /* Configure Button pin as input */
    gpioinitstruct.Mode = GPIO_MODE_INPUT;
    HAL_GPIO_Init(BUTTON_PORT[Button], &gpioinitstruct);
  }
  else if (Button_Mode == BUTTON_MODE_EXTI)
  {
    if(Button != BUTTON_WAKEUP)
    {
      /* Configure Joystick Button pin as input with External interrupt, falling edge */
      gpioinitstruct.Mode = GPIO_MODE_IT_FALLING;
    }
    else
    { 
      /* Configure Key Push Button pin as input with External interrupt, rising edge */
      gpioinitstruct.Mode = GPIO_MODE_IT_RISING;
    }
    HAL_GPIO_Init(BUTTON_PORT[Button], &gpioinitstruct);

    /* Enable and set Button EXTI Interrupt to the lowest priority */
    HAL_NVIC_SetPriority((IRQn_Type)(BUTTON_IRQn[Button]), 0x0F, 0);
    HAL_NVIC_EnableIRQ((IRQn_Type)(BUTTON_IRQn[Button]));
  }
}

/**
  * @brief  Returns the selected button state.
  * @param  Button: Button to be checked.
  *   This parameter can be one of the following values:
  *     @arg BUTTON_TAMPER: Key/Tamper Push Button 
  * @retval Button state
  */
uint32_t BSP_PB_GetState(Button_TypeDef Button)
{
  return HAL_GPIO_ReadPin(BUTTON_PORT[Button], BUTTON_PIN[Button]);
}

/**
  * @brief  Configures LED GPIO.
  * @param  Led: Specifies the Led to be configured. 
  *   This parameter can be one of following parameters:
  *     @arg PWR1
  *     @arg PWR2
  *     @arg PWR3
  *     @arg PWR4
  */
void BSP_RS485_Init(Rs485_TypeDef Rs485)
{
  GPIO_InitTypeDef  gpioinitstruct = {0};
  
  /* Enable the GPIO_LED clock */
  RS485x_GPIO_CLK_ENABLE(Rs485);

  /* Configure the GPIO_LED pin */
  gpioinitstruct.Pin    = RS485_PIN[Rs485];
  gpioinitstruct.Mode   = GPIO_MODE_OUTPUT_PP;
  gpioinitstruct.Pull   = GPIO_NOPULL;
  gpioinitstruct.Speed  = GPIO_SPEED_FREQ_HIGH;

  HAL_GPIO_Init(RS485_PORT[Rs485], &gpioinitstruct);

  HAL_GPIO_WritePin(RS485_PORT[Rs485], RS485_PIN[Rs485], GPIO_PIN_RESET);
}

/**
  * @brief  Turns selected LED On.
  * @param  Led: Specifies the Led to be set on. 
  *   This parameter can be one of following parameters:
  *     @arg PWR1
  *     @arg PWR2
  *     @arg PWR3
  *     @arg PWR4
  */
void BSP_RS485_On(Rs485_TypeDef Rs485)
{
  HAL_GPIO_WritePin(RS485_PORT[Rs485], RS485_PIN[Rs485], GPIO_PIN_SET);
}

/**
  * @brief  Turns selected LED Off.
  * @param  Led: Specifies the Led to be set off. 
  *   This parameter can be one of following parameters:
  *     @arg PWR1
  *     @arg PWR2
  *     @arg PWR3
  *     @arg PWR4
  */
void BSP_RS485_Off(Rs485_TypeDef Rs485)
{
  HAL_GPIO_WritePin(RS485_PORT[Rs485], RS485_PIN[Rs485], GPIO_PIN_RESET);
}

/**
  * @brief  watch dog init.
  * @param  NONE
  */
void BSP_WDG_Init(void)
{
    GPIO_InitTypeDef gpioinitstruct = {0};

    /* Enable the GPIO_LED clock */
    WDG_GPIO_CLK_ENABLE();

    /* Configure the GPIO_LED pin */
    gpioinitstruct.Pin = WDG_PIN;
    gpioinitstruct.Mode = GPIO_MODE_OUTPUT_PP;
    gpioinitstruct.Pull = GPIO_PULLUP;
    gpioinitstruct.Speed = GPIO_SPEED_FREQ_LOW;
    
    HAL_GPIO_Init(WDG_GPIO_PORT, &gpioinitstruct);
}

/**
  * @brief  watch dog init.
  * @param  NONE
  */
void BSP_WDG_Feed(void)
{
    HAL_GPIO_TogglePin(WDG_GPIO_PORT, WDG_PIN);
}